<?php
/**
 * Created by PhpStorm.
 * User: Qch
 * Date: 2016/10/29
 * Time: 16:56
 */

namespace J\Util;


use J\TReadOnly;
use J\ReturnValue;

/**
 * 当前登录用户信息
 *
 * @property string name      用户名
 * @property string nickname  昵称
 * @property int    id
 *
 * @property array  authorize   权限数组
 * @property array  roles       角色数组
 * @property array  departments 部门数组
 *
 *
 */
abstract class User
{
    use TReadOnly { get as readonlyGet; }

    const KEY_DEPARTMENTS   = 'departments';
    const KEY_ROLES         = 'roles';
    const KEY_AUTHORIZE     = 'authorize';
    const KEY_ID            = 'id';

    const USER_SESSION_KEY  = 'User';

    protected $reload = true;

    protected static $mixed = [
        self::KEY_ROLES        => true,
        self::KEY_AUTHORIZE    => true,
        self::KEY_DEPARTMENTS  => true
    ];

    /**
     * @var bool
     */
    protected $isLogin = false;

    protected $id = -1;

    public function isLogin()
    {
        return $this->isLogin;
    }

    public function logout()
    {
        $this->attributes = [];
        $this->isLogin = false;
    }

    /**
     * 登陆指定用户
     *
     * @param array $attributes 用户信息
     * @return void
     */
    public function login(array $attributes)
    {
        $this->isLogin = true;
        $this->attributes = $attributes;
    }

    public function get($key = null, $default = null)
    {
        $func = strtolower($key);
        // 普通属性
        if(!isset(static::$mixed[$func])) return $this->readonlyGet($key, $default);
        // 尚未登陆
        if(!$this->isLogin()) return false;
        // 权限获取
        if(!isset($this->attributes[$func]) or $this->reload){
            $values =  $this->getMyInformation($func);
            if($values->isError()) return false;
            // 自动缓存
            $this->fill($func,$values->getValue());
        }
        return $this->attributes[$func];
    }

    protected function fill($key, $value)
    {
        array_set($this->attributes,$key,$value);
    }

    /**
     * 获取用户信息
     * @param string $information
     * @return ReturnValue
     */
    abstract protected function getMyInformation($information);

    /**
     * 权限判断
     * @param string $operator
     *
     * @return bool
     */
    public function authorized($operator)
    {
        if($this->isAdministrator()) return true;
        return $this->authorize($operator);
    }

    /**
     * @param $id
     * @return bool
     */
    public function isMe($id)
    {
        return $this->attributes['id']  == $id;
    }

    public function isAdministrator()
    {
        // TODO  深化超级管理员判断
        return ($this->getId() == 1);
    }

    public function getId()
    {
        if ($this->id === -1)
            $this->id = (int)(array_isset($this->attributes,'id',0));

        return $this->id;
    }

    /**
     * 核对权限信息
     *
     * @param string $operator
     * @return bool
     */
    protected function authorize($operator)
    {
        $options = $this->authorize;
        if(empty($options)) return false;

        $operator = strtolower(trim($operator,'/'));

        foreach($options as $option){
            if((strtolower(trim($option['url'],'/'))) === $operator) return true;
        }
        return false;
    }
}